//
//  NSError+MujiVideo.h
//  SampleApp
//
//  Created by Samuel Chow on 8/28/13.
//  Copyright (c) 2013 MujiVideo. All rights reserved.
//
//  Modifiied from Mikhail Dudarev's (mikejd@mikejd.ru) Speex Encoder.
//

#import "NSError+MujiVideo.h"
//#import "ECCoreLibraryConstants.h"

NSString * const ECMujiVideoDomain       = @"com.MujiVideo.SDK";


@implementation NSError (MujiVideo)

+ (NSError *)errorWithCode:(MujiVideoErrorCode)errorCode
{
    NSString *localizedDescription    = [NSError localizedDescriptionWithCode:errorCode];
    NSString *localizedFailureReason  = [NSError localizedFailureReasonWithCode:errorCode];
    NSArray *localizedRecoveryOptions = [NSError localizedRecoveryOptionsWithCode:errorCode];
    NSDictionary *userInfo            = @{NSLocalizedDescriptionKey        : localizedDescription,
                                          NSLocalizedFailureReasonErrorKey : localizedFailureReason};
    if (localizedRecoveryOptions)
    {
        userInfo = @{NSLocalizedDescriptionKey          : localizedDescription,
                     NSLocalizedFailureReasonErrorKey   : localizedFailureReason,
                     NSLocalizedRecoveryOptionsErrorKey : localizedRecoveryOptions};
    }
    
    return [NSError errorWithDomain:ECMujiVideoDomain
                               code:errorCode
                           userInfo:userInfo];
}


+ (NSString *)localizedDescriptionWithCode:(MujiVideoErrorCode)errorCode
{
    NSString *localizedDescription;
    switch (errorCode)
    {
        case MujiVideoErrorCodeGeneral:
            localizedDescription = NSLocalizedString(@"General Error", nil);
            break;
        case MujiVideoErrorCodeWavParserIncorrectFileSize:
        case MujiVideoErrorCodeWavParserContainerIDNotFound:
        case MujiVideoErrorCodeWavParserFormatIDNotFound:
        case MujiVideoErrorCodeWavParserDataChunkIDNotFound:
        case MujiVideoErrorCodeWavParserAudioPropertiesNotExtracted:
            localizedDescription = NSLocalizedString(@"Audio Parser Error", nil);
            break;
        case MujiVideoErrorCodeSpeexEncoderFailedToAllocateEncoderState:
        case MujiVideoErrorCodeSpeexEncoderFailedToSetUpResampler:
        case MujiVideoErrorCodeSpeexEncoderFailedToObtainFrameSize:
        case MujiVideoErrorCodeSpeexEncoderFailedToObtainBitrate:
        case MujiVideoErrorCodeSpeexEncoderFailedToSetQuality:
        case MujiVideoErrorCodeSpeexEncoderNotEnoughDataToCreateSpeexHeader:
            localizedDescription = NSLocalizedString(@"Speex Encoder Error", nil);
            break;
        case MujiVideoErrorCodeOggFailedToAllocateStreamState:
            localizedDescription = NSLocalizedString(@"Ogg Encoder Error", nil);
            break;
        case MujiVideoErrorCodeFailedToCreateFile:
            localizedDescription = NSLocalizedString(@"File Error", nil);
            break;
        case MujiVideoErrorCodeAssetNotPlayable:
        case MujiVideoErrorCodeAssetBadMediaURL:
        case MujiVideoErrorCodeAssetFailedLoading:
        case MujiVideoErrorCodeAssetPlaybackTimeout:
        case MujiVideoErrorCodeDownloadingOfContentFailed:
        case MujiVideoErrorCodeUserAccountNotLoggedIn:
        case MujiVideoErrorCodeUserAccountDoesNotContainStudentClassIDs:
        case MujiVideoErrorCodeAssetMaximumRetryReached:
        case MujiVideoErrorCodeSpeechDialogLineAnalysisResultRejected:
        case MujiVideoErrorCodeInvalidDialogLineSpeechUploadRecord:
        case MujiVideoErrorCodeInvalidDeviceToken:
        case MujiVideoErrorCodeMediaCacheInvalidURL:
        case MujiVideoErrorCodeRequestSerializationInvalidRequest:
        case MujiVideoErrorCodeGenericSpeechAnalysisError:
        case MujiVideoErrorCodeMissingEmailPasswordError:
            localizedDescription = NSLocalizedString(@"Error", nil);
            break;
        case MujiVideoErrorCodePurchasedInAppProductNotFound:
        case MujiVideoErrorCodeCannotConnectToAppStore:
        case MujiVideoErrorCodeFailedToProcessPayment:
            localizedDescription = NSLocalizedString(@"In-App Purchase", @"Title to display for an error relating to In-App Purchases");
            break;
        case MujiVideoErrorCodeAccountRegistrationFailure:
            localizedDescription = NSLocalizedString(@"Registration Error", nil);
            break;
        case MujiVideoErrorCodeMediaCacheImageDownloadFailure:
        case MujiVideoErrorCodeMediaCacheAudioDownloadFailure:
            localizedDescription = NSLocalizedString(@"Media Error", nil);
            break;
        case MujiVideoErrorCodeInAppPurchaseNotEnabled:
        case MujiVideoErrorCodePaymentAlreadyProcessing:
        case MujiVideoErrorCodePaymentAlreadyPurchased:
        case MujiVideoErrorCodePaymentIsRestoring:
        case MujiVideoErrorCodePaymentIsPendingExternalAction:
        case MujiVideoErrorCodeUnableToCompleteTransaction:
            localizedDescription = NSLocalizedString(@"Paywall Error",
                                                     @"The title for an error alert message that is displayed when the user tries to buy a product from In-App Purchase store when it is disabled");
            break;
        case MujiVideoErrorCodeSocialShareUserCancelled:
        case MujiVideoErrorCodeSocialShareGeneralError:
        case MujiVideoErrorCodeSocialShareNativeFacebookAppNotInstalled:
            localizedDescription = NSLocalizedString(@"Social Service Error",
                                                     @"The title for an error alert message prompt that is displayed when an error was encounterd during the social sharing feature");
            break;
        default:
            localizedDescription = NSLocalizedString(@"Unknown Error", nil);
            break;
    }
    
    return localizedDescription;
}


+ (NSString *)localizedFailureReasonWithCode:(MujiVideoErrorCode)errorCode
{
    NSString *failureReason;
    
    switch (errorCode)
    {
        case MujiVideoErrorCodeGeneral:
            failureReason = NSLocalizedString(@"A general error was encountered", nil);
            break;
        case MujiVideoErrorCodeWavParserIncorrectFileSize:
            failureReason = NSLocalizedString(@"Failed to parse audio from a file with incorrect size", @"Wave file parser error message");
            break;
        case MujiVideoErrorCodeWavParserContainerIDNotFound:
        case MujiVideoErrorCodeWavParserFormatIDNotFound:
        case MujiVideoErrorCodeWavParserDataChunkIDNotFound:
            failureReason = NSLocalizedString(@"Failed to parse invalid data", @"Wave file parser error message");
            break;
        case MujiVideoErrorCodeWavParserAudioPropertiesNotExtracted:
            failureReason = NSLocalizedString(@"Failed to extract audio properties", @"Wave file parser error message");
            break;
        case MujiVideoErrorCodeSpeexEncoderFailedToAllocateEncoderState:
            failureReason = NSLocalizedString(@"Failed to allocate speex encoder state", @"Speex encoder error message");
            break;
        case MujiVideoErrorCodeSpeexEncoderFailedToSetUpResampler:
            failureReason = NSLocalizedString(@"Failed to set up resampler", @"Speex encoder error message");
            break;
        case MujiVideoErrorCodeSpeexEncoderFailedToObtainFrameSize:
            failureReason = NSLocalizedString(@"Failed to obtain frame size", @"Speex encoder error message");
            break;
        case MujiVideoErrorCodeSpeexEncoderFailedToObtainBitrate:
            failureReason = NSLocalizedString(@"Failed to obtain bitrate", @"Speex encoder error message");
            break;
        case MujiVideoErrorCodeSpeexEncoderFailedToSetQuality:
            failureReason = NSLocalizedString(@"Failed to set quality", @"Speex encoder error message");
            break;
        case MujiVideoErrorCodeSpeexEncoderNotEnoughDataToCreateSpeexHeader:
            failureReason = NSLocalizedString(@"Not enough data to create speex header", @"Speex encoder error message");
            break;
        case MujiVideoErrorCodeOggFailedToAllocateStreamState:
            failureReason = NSLocalizedString(@"Failed to allocate stream state", @"Ogg encoder error message");
            break;
        case MujiVideoErrorCodeFailedToCreateFile:
            failureReason = NSLocalizedString(@"Failed to create file at specified path", nil);
            break;
        case MujiVideoErrorCodeAssetNotPlayable:
            failureReason = NSLocalizedString(@"Unable to play the video at this time. Please check your network connectivity and try again at a later time.", nil);
            break;
        case MujiVideoErrorCodeAssetBadMediaURL:
        case MujiVideoErrorCodeAssetFailedLoading:
        case MujiVideoErrorCodeAssetPlaybackTimeout:
            failureReason = NSLocalizedString(@"The video is taking longer to load than expected.", nil);
            break;
        case MujiVideoErrorCodeAssetMaximumRetryReached:
            failureReason = NSLocalizedString(@"Video failed to load.  Please try again at a later time.", nil);
            break;
        case MujiVideoErrorCodeDownloadingOfContentFailed:
            failureReason = NSLocalizedString(@"Unable to download requested content.  Please try again at a later time.", @"Message to display to user when downloading of content has failed");
            break;
        case MujiVideoErrorCodeUserAccountNotLoggedIn:
            failureReason = NSLocalizedString(@"Account not found.  Please sign in.", @"Message that is display to the user in the case that the user's account is not logged in");
            break;
        case MujiVideoErrorCodeUserAccountDoesNotContainStudentClassIDs:
            failureReason = NSLocalizedString(@"Your account does not contain any classes.", @"Message that is displayed to the user in the case that their account does not contain any classes.");
            break;
        case MujiVideoErrorCodePurchasedInAppProductNotFound:
            failureReason = NSLocalizedString(@"Could not find a purchased product for specified account.", @"The error message that is displayed to the user when they have not purchased a product from In-App Purchase");
            break;
        case MujiVideoErrorCodeCannotConnectToAppStore:
            failureReason = NSLocalizedString(@"A connection to the App Store could not be established at this time. Please try again later.",
                                              @"Message that will be displayed to the user to let them know that a connection could not be established with the iTunes App Store");
            break;
        case MujiVideoErrorCodeFailedToProcessPayment:
            failureReason = NSLocalizedString(@"Your In-App Purchase cannot be completed at this time. Please try again later.", nil);
            break;
        case MujiVideoErrorCodeInvalidDeviceToken:
            failureReason = NSLocalizedString(@"Invalid device token detected", @"Error message displayed to the user when the device token was not valid");
            break;
        case MujiVideoErrorCodeAccountRegistrationFailure:
            failureReason = NSLocalizedString(@"Failed to register your account. Please try again.", nil);
            break;
        case MujiVideoErrorCodeMediaCacheImageDownloadFailure:
            failureReason = NSLocalizedString(@"Unable to download requested image at this time. Please check your network connection and try again.", nil);
            break;
        case MujiVideoErrorCodeMediaCacheAudioDownloadFailure:
            failureReason = NSLocalizedString(@"Unable to download requested audio at this time. Please check your network connection and try again.", nil);
            break;
        case MujiVideoErrorCodeMediaCacheInvalidURL:
            // This is not to be localized.  Its a more of a developer error code.
            failureReason = @"Cannot download media with invalid URL.";
            break;
        case MujiVideoErrorCodeRequestSerializationInvalidRequest:
            // This is not to be localized.  Its a developer error code.
            failureReason = @"Cannot serialize an invalid NSURLRequest";
            break;
        case MujiVideoErrorCodeInAppPurchaseNotEnabled:
            failureReason = NSLocalizedString(@"In-App Purchasing is disabled for this application. The requested transaction cannot be processed.",
                                              @"The message that will be displayed to the user explaining that they have tried to purchase an In-App product but that this functionality has been disabled");
            break;
        case MujiVideoErrorCodePaymentAlreadyProcessing:
            failureReason = NSLocalizedString(@"A payment has already been submitted and is being processed. Please wait until the transaction has finished.",
                                              @"The message that will be displayed to the user explaining that they have already submitted a payment transaction");
            break;
        case MujiVideoErrorCodePaymentAlreadyPurchased:
        case MujiVideoErrorCodePaymentIsRestoring:
            failureReason = NSLocalizedString(@"You have already made this purchase.", @"The message that is displayed to the user to let them know that they have already purchased this product.");
            break;
        case MujiVideoErrorCodePaymentIsPendingExternalAction:
            failureReason = NSLocalizedString(@"The payment is being processed, but its final status is pending external action.",
                                              @"The message that is displayed to the user to let them know that their submitted payment transaction is processing but is pending external action before it can be finished");
            break;
        case MujiVideoErrorCodeUnableToCompleteTransaction:
            failureReason = NSLocalizedString(@"The requested payment was unable to complete at this time. Please check to ensure you have a network connection and try again.",
                                              @"The message that is displayed to the user to alert them that the requested payment transaction is unable to complete either due to connection issues or internal system issues");
            break;
        case MujiVideoErrorCodeGenericSpeechAnalysisError:
            failureReason = NSLocalizedString(@"Something went wrong during speech processing.", nil);
            break;
        case MujiVideoErrorCodeSocialShareUserCancelled:
            failureReason = NSLocalizedString(@"The social sharing request was cancelled.", nil);
            break;
        case MujiVideoErrorCodeSocialShareGeneralError:
            failureReason = NSLocalizedString(@"Unable to complete your sharing request at this time.  Please check your device settings and make sure that you are logged into the social service and try again.", nil);
            break;
        case MujiVideoErrorCodeSocialShareNativeFacebookAppNotInstalled:
            failureReason = NSLocalizedString(@"Unable to complete your Facebook sharing request at this time.  Please make sure that the Facebook app is installed on your device and that you are signed into your Facebook account and try again.", nil);
            break;
        case MujiVideoErrorCodeMissingEmailPasswordError:
            failureReason = NSLocalizedString(@"Email and password are required to register a new account", nil);
            break;
        default:
            failureReason = NSLocalizedString(@"An unknown error was encountered", nil);
            break;
    }
    
    return failureReason;
}

/*
 NSString *localizedDescription   =  NSString *localizedFailureReason = nil;
 switch (errorCode)
 {
 case ECPaywallManagerErrorCodeInAppPurchaseNotEnabled:
 
 break;
 case ECPaywallManagerErrorCodePaymentAlreadyProcessing:
 localizedFailureReason
 break;
 case ECPaywallManagerErrorCodePaymentIsPendingExternalAction:
 localizedFailureReason
 break;
 case ECPaywallManagerErrorCodePaymentAlreadyPurchased:
 case ECPaywallManagerErrorCodePaymentIsRestoring:
 localizedFailureReason =
 break;
 case ECPaywallManagerErrorCodeUnableToCompleteTransaction:
 localizedFailureReason
 break;
 }
 */


+ (NSArray *)localizedRecoveryOptionsWithCode:(MujiVideoErrorCode)errorCode
{
    NSArray *options = nil;
    switch (errorCode)
    {
        case MujiVideoErrorCodeGeneral:
        case MujiVideoErrorCodeWavParserIncorrectFileSize:
        case MujiVideoErrorCodeWavParserContainerIDNotFound:
        case MujiVideoErrorCodeWavParserFormatIDNotFound:
        case MujiVideoErrorCodeWavParserDataChunkIDNotFound:
        case MujiVideoErrorCodeWavParserAudioPropertiesNotExtracted:
        case MujiVideoErrorCodeSpeexEncoderFailedToAllocateEncoderState:
        case MujiVideoErrorCodeSpeexEncoderFailedToSetUpResampler:
        case MujiVideoErrorCodeSpeexEncoderFailedToObtainFrameSize:
        case MujiVideoErrorCodeSpeexEncoderFailedToObtainBitrate:
        case MujiVideoErrorCodeSpeexEncoderFailedToSetQuality:
        case MujiVideoErrorCodeSpeexEncoderNotEnoughDataToCreateSpeexHeader:
        case MujiVideoErrorCodeOggFailedToAllocateStreamState:
        case MujiVideoErrorCodeFailedToCreateFile:
        case MujiVideoErrorCodeAssetNotPlayable:
        case MujiVideoErrorCodeCannotConnectToAppStore:
        case MujiVideoErrorCodeFailedToProcessPayment:
        case MujiVideoErrorCodeAssetMaximumRetryReached:
        case MujiVideoErrorCodeSpeechDialogLineAnalysisResultRejected:
        case MujiVideoErrorCodeInvalidDialogLineSpeechUploadRecord:
            options = @[NSLocalizedString(@"OK", @"Title for a button displayed in an alert view")];
            break;
        case MujiVideoErrorCodeGenericSpeechAnalysisError:
            options = @[NSLocalizedString(@"Retry Processing", @"This is text for a button.  We need the translations to be as short as possible as this button will need to be displayed next to another button with text 'New Recording'."),
                       NSLocalizedString(@"New Recording", @"This is text for a button.  We need the translations to be as short as possible as this will button will need to be displayed next to a button with text 'Retry Processing'")];
            break;
        case MujiVideoErrorCodeAssetBadMediaURL:
        case MujiVideoErrorCodeAssetFailedLoading:
            options = @[NSLocalizedString(@"Cancel", @"Title of a Cancel button"),
                        NSLocalizedString(@"Retry Loading", @"Title of a button that a user can select to retry loading of a video")];
            break;
        case MujiVideoErrorCodeAssetPlaybackTimeout:
            options = @[NSLocalizedString(@"Cancel", @"Title of a Cancel button"),
                        NSLocalizedString(@"Continue Waiting", @"Title of a button that a user can select to give a video more time to load.")];
            break;
        default:
            break;
    }
    
    return options;
}


#pragma mark -
#pragma mark Public Methods

- (BOOL)isIdentifyingNetworkConnectionIssue
{
    switch (self.code)
    {
        case NSURLErrorNotConnectedToInternet: return YES;
        case NSURLErrorDataNotAllowed: return YES;
        case NSURLErrorNetworkConnectionLost: return YES;
        case NSURLErrorCannotConnectToHost: return YES;
        case NSURLErrorCannotFindHost: return YES;
        default: return NO;
    }
}

- (BOOL)isUnauthorizedError
{
    switch (self.code)
    {
        case 401:
        case NSURLErrorUserAuthenticationRequired:
        case NSURLErrorUserCancelledAuthentication:
        case NSURLErrorNoPermissionsToReadFile:
        case NSURLErrorSecureConnectionFailed:
        case NSURLErrorClientCertificateRequired:
            return YES;
        default:
            return NO;
    }
}



@end
